package com.fvff.sanctuary.dao;

import java.util.List;


/**
 * Generic DAO (Data Access Object) with common methods to CRUD POJOs.
 * Only supports PK type of Long.
 *
 * @param <T> a type variable
 */
public interface GenericDao<T> {

    /**
     * Generic method used to get all objects of a particular type. This
     * is the same as lookup up all rows in a table.
     *
     * @return List of populated objects
     */
    List<T> getAll();

    /**
     * Queries all objects with pagination.
     * WARNING: Pagination works correctly only if orderBy column has a unique index.
     * However, if index is set to zero, maxRows works correctly, even if the
     * orderBy column is not unique.
     * <p/>
     * Another WARNING:  maxRows is sent to Oracle.  If the model being
     * queried has EAGER loaded OneToMany associations, there will be an
     * additional row fetched for each of the associations greater than one.
     * The size of the list returned will be equal or smaller to maxRows, but
     * there may be duplicate objects in the list.
     *
     * @param index     the zero-based index of the first result
     * @param maxRows   the maximum number of rows to return
     * @param orderBy   name of the field to order by
     * @param ascending if true, order is ascending, else descending
     * @return List of populated objects
     */
    List<T> paginateAll(int index, int maxRows, String orderBy, boolean ascending);

    /**
     * Generic method to get an object based on class and identifier. An
     * ObjectRetrievalFailureException Runtime Exception is thrown if
     * nothing is found.
     *
     * @param id the identifier (primary key) of the object to get
     * @return a populated object
     * @throws org.springframework.orm.ObjectRetrievalFailureException
     *
     */
    T get(Long id);

    /**
     * Generic method to get an object based on class and identifier.
     *
     * @param id the identifier (primary key) of the object to get
     * @return a populated object or null if non-existent
     */
    T getIfExists(Long id);

    /**
     * Checks for existence of an object of type T using the id arg.
     *
     * @param id the id of the entity
     * @return - true if it exists, false if it doesn't
     */
    boolean exists(Long id);

    /**
     * Generic method to save an object - handles both update and insert.
     *
     * @param object the object to save
     * @return the persisted object
     */
    T save(T object);

    Long create(T object);

    /**
     * Flush the session.
     */
    void flush();

    /**
     * Flush and clear the session.
     */
    void flushClear();

    /**
     * Generic method to delete an object based on class and id
     *
     * @param id the identifier (primary key) of the object to remove
     */
    void remove(Long id);
}
